/**********************************************************************************/
/*code intellisense.cpp                                                           */
/*Description:                                                                    */
/*Input:  A piece of C/C++ source code                                            */  
/*Output: 1.Prototype of the function called at the end of this piece of code.    */    
/*          2.Identify which parameter is being inputted.                         */
/*                                                                                */
/*Example:                                                                        */
/*Input:    -int foo (int a, unsigned char b) {                                   */
/*          -    return 0;                                                        */
/*          -}                                                                    */
/*          -void bar() {                                                         */
/*          -    foo(10,                                                          */
/*Output:                                                                         */
/*          -int foo (int, unsigned char)                                         */
/*          -2                                                                    */ 
/**********************************************************************************/


#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;

#define MAX 38
/* ANSI C keywords*/
string Key[] = {"auto", "short", "int", "long", "float", "double", "char", "struct", "union",
"enum", "typedef", "const", "unsigned", "signed", "extern", "register", "static",
"volatile", "void", "if", "else", "switch", "case", "for", "do", "while", "goto",
"continue", "break", "default", "sizeof", "return", "inline", "restrict", "bool",
"imaginary", "generic", "complex"};

/*identify letters*/
int IsLetter(char c)    
{        
	if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))) 
		return 1;
	else 
		return 0;
}

/*identify digits*/
int IsDigit(char c)    
{          
	if (c >= '0' && c <= '9') 
		return 1;
	else 
		return 0;
}

/* identify keywords */
int IsKey(string c)     
{          
	int i;
	for (i = 0; i < MAX; i++) 
	{
		if (Key[i].compare(c) == 0) 
			return 1;      
	} 
	return 0;
}

#define N 50
struct function         /*define the structure for function*/
{                       /*a function usually consists of the followings: */
	string keyword;     /*return type*/
	string name;        /*name*/  
	string parameter;   /*parameters*/
}func[N];

/* utilize the principle of scanner to implement this code intellisense */
void scanner(FILE *f)
{
	char ch = ' ';        
	string str = "";       
	int i = 0;            
	int isfget = 0;      

	ch = fgetc(f);
	isfget = 1;
	while (ch != EOF)
	{
		if (isfget == 0)
		{
			ch = fgetc(f);
			isfget = 1;
			continue;
		}
		else
		{
			isfget = 0;
		}

		str = "";    

		if ((ch == '\n') && (func[i].keyword != "") && (func[i].name != "") && (func[i].parameter != ""))
		{
			i++;
		}
		else if ((ch == '\n') && ((func[i].keyword == "") || (func[i].name == "") || (func[i].parameter == "")))
		{
			func[i].keyword = "";
			func[i].name = "";
			func[i].parameter = "";
		}

		if (ch == 32)
		{   
			while (ch == 32)
			{	    
				ch = fgetc(f);
			}
			isfget = 1;
		}
		else if (ch == '\t')
		{   
			while (ch == '\t')
			{	    
				ch = fgetc(f);
			}
			isfget = 1;
		}
		else if (IsLetter(ch) || (ch == '_'))
		{
			while (IsLetter(ch) || IsDigit(ch) || (ch == '_'))
			{ 	 
				str = str + ch;		
				ch = fgetc(f);
				isfget = 1;
			}
			if ((IsKey(str) == 1) && (func[i].name == "") && (func[i].parameter == ""))    
			{
				func[i].keyword = func[i].keyword + str + ' ';			
			}
			else if ((IsKey(str) == 0) && (func[i].keyword != "") && (func[i].parameter == ""))          
			{
				func[i].name = str;
			}
			else if ((IsKey(str) == 1) && (func[i].keyword != "") && (func[i].name != "") && (func[i].parameter != ""))             
			{
				func[i].parameter = func[i].parameter + " " +str;
			}
		}

		/*the parameters of a function always start with "("*/
		else if (ch == '(')
		{
			if (func[i].keyword != "" && func[i].name != "")
			{
				func[i].parameter = "(";
			}
			ch = fgetc(f);
			isfget = 1;
			if((func[i].keyword != "") && (func[i].name != ""))
			{
				if(IsLetter(ch))
				{
					isfget = 0;
					while (IsLetter(ch))
					{ 	 
						str = str + ch;		
						ch = fgetc(f);
						isfget = 1;
					}
					if ((IsKey(str) == 1) && (func[i].keyword != "") && (func[i].name != "") && (func[i].parameter != ""))             
					{
						func[i].parameter = func[i].parameter + str;
					}
				}
			}
		}
		else if ((ch == ',') && (func[i].keyword != "") && (func[i].name != "") && (func[i].parameter != ""))
		{
			func[i].parameter = func[i].parameter + ",";
		}
		else if ((ch == ')') && (func[i].keyword != "") && (func[i].name != "") && (func[i].parameter != ""))
		{
			func[i].parameter = func[i].parameter + ")";
		}
	}
}

/* parser */
void parser(FILE *f)
{
	char str1[20000];    
	int n, m, flen;

	fseek(f, 0, SEEK_END);
	flen = ftell(f);
	fseek(f, 0, SEEK_SET);
	for(n = 0; n < flen; n++)  
	{
		fscanf(f, "%c", &str1[n]);
	}

	for(m = flen-1; m > 0; m--)    
	{
		if(str1[m] == '\n')
			break;
	}

	string str2 = "";     
	int j; 
	for(j = m+1; j < flen; j++)
	{
		if(str1[j] == '(')
		{
			break;
		}
		else if(str1[j] != 32)
		{
			str2 = str2 + str1[j];	
		}	
	}

	string s1 = "";
	string s2 = "";
	string s3 = "";
	for(int i = 0; i < N; i++)
	{
		if(str2 == func[i].name)
		{
			s1 = func[i].keyword;
			s2 = func[i].name;
			s3 = func[i].parameter;
			break;
		}
	}
	cout<<s1<<s2<<s3<<endl;  

	int num;           
	if((s3 == "()") || (s3 == "(void)"))
	{
		num = 0;
	}	
	else 
	{        
		num = 1;        
		for(j = m+1; j < flen; j++)
		{
			if(str1[j] == ',')
			{
				num++;
			}         
		}
	}
	cout<<num<<endl;   
}

int main()
{
	function func[N];
	char in_fn[5000];
	FILE *f;
	cout<<"Please input the filename and directory:"<<endl;
	for (;;)
	{
		cin>>in_fn;
		if ((f = fopen(in_fn,"r")) != NULL) 
			break;
		else 
		{
			cout<<"Error! No such file or directory."<<endl;
			cout<<"Please input the filename and directory again:"<<endl;		
		}
	}
	cout<<"\n********************Result of Code Intellisense*********************"<<endl;
	scanner(f);
	parser(f);
	fclose(f);
	system ("PAUSE");
	return 0; 
}
